
import numpy as np
import matplotlib.pyplot as plt
from Interpolator import Interpolator
class LagrangeInterpolator(Interpolator):
    def __init__(self, x_points, y_points):
        """
        初始化拉格朗日插值器
        :param x_points: 已知点的 x 坐标列表
        :param y_points: 已知点的 y 坐标列表
        """
        self.x_points = np.array(x_points)
        self.y_points = np.array(y_points)

    def lagrange_basis(self, x, j):
        """
        计算拉格朗日基函数
        :param x: 待插值点的 x 坐标
        :param j: 基函数的索引
        :return: 拉格朗日基函数的值
        """
        n = len(self.x_points)
        basis = 1
        for i in range(n):
            if i != j:
                basis *= (x - self.x_points[i]) / (self.x_points[j] - self.x_points[i])
        return basis


    def interpolate(self, x):
        """
        进行拉格朗日插值计算
        :param x: 待插值点的 x 坐标
        :return: 插值点的 y 坐标
        """
        n = len(self.x_points)
        y = 0
        for j in range(n):
            y += self.y_points[j] * self.lagrange_basis(x, j)
        return y


# 示例使用
if __name__ == "__main__":
    # 已知点的 x 坐标
    x_points = [1, 2, 3, 4, 5, 6, 7, 8]
    # 已知点的 y 坐标
    y_points = [2, 3, 5, 7, 11, 13, 17, 19]

    # 创建拉格朗日插值器对象
    interpolator = LagrangeInterpolator(x_points, y_points)

    # 待插值点
    x_interpolate = 2.5
    # 进行插值计算
    y_interpolate = interpolator.interpolate(x_interpolate)
    print(f"在 x = {x_interpolate} 处的插值结果为: {y_interpolate}")

    # 可以多次使用插值器进行不同点的插值
    x_another = 3.2
    y_another = interpolator.interpolate(x_another)
    print(f"在 x = {x_another} 处的插值结果为: {y_another}")
    plt.rcParams['figure.dpi'] = 300
    plt.figure(figsize=(10, 6))

    # 绘制折线图
    plt.plot(x_points, y_points, color='blue', label='Data Line')

    plt.title('Line Plot of Given Points')
    plt.xlabel('X-axis')
    plt.ylabel('Y-axis')
    plt.grid(True)
    plt.legend()
    plt.show()